/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.imports;

import cz.mzk.rehan.commons.DatastreamId;
import cz.mzk.rehan.commons.Dom4jUtils;
import cz.mzk.rehan.commons.Namespaces;
import java.io.File;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import cz.mzk.rehan.commons.RandomBasedUuidGenerator;
import cz.mzk.rehan.commons.UuidGenerator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Node;
import org.dom4j.XPath;

/**
 *
 * @author Martin Rehanek (rehan@mzk.cz)
 */
public final class FoxmlHelper {

    private static final Logger logger = Logger.getLogger(FoxmlHelper.class.getName());
    private static final UuidGenerator uuidGenerator = RandomBasedUuidGenerator.instanceOf();

//    public FoxmlHelper() {
//        //uuidGenerator = EthAddrUuidGenerator.instanceOf(properties);
//        uuidGenerator = RandomBasedUuidGenerator.instanceOf();
//    }

    public static Datastream createPolicyDatastream(Policy policy) {
        String policyUrl = null;
        switch (policy) {
            case PRIVATE:
                policyUrl = "http://local.fedora.server/fedora/get/policy:private/POLICYDEF";
                break;
            case PUBLIC:
                policyUrl = "http://local.fedora.server/fedora/get/policy:public/POLICYDEF";
                break;
        }
        return DatastreamFactory.createExternalyReferencedDs(policyUrl, DatastreamId.POLICY);
    }

    public static String generateUuid() {
        return uuidGenerator.generateUuid();
    }

    public static void saveFoxml(File dir, Foxml foxml) {
        Document foxmlDoc = foxml.getFoxmlWithDatastreams();
        File saveTo = new File(dir.getAbsolutePath() + File.separator + foxml.getUuid() + ".xml");
        Dom4jUtils.saveDocument(foxmlDoc, saveTo);
        logger.log(Level.INFO, "saving foxml file: {0}", saveTo.getAbsolutePath());
    }

    public static Document createRelsExtSkeleton(Foxml foxml, String model, Policy policy) {
        Namespace rdfNs = Namespaces.rdf;
        Namespace krameriusNs = Namespaces.kramerius;
        Element rootElement = DocumentHelper.createElement(new QName("RDF", rdfNs));
        rootElement.add(rdfNs);
        rootElement.add(krameriusNs);
        Document doc = DocumentHelper.createDocument(rootElement);
        Element description = rootElement.addElement(new QName("Description", rdfNs));
        description.addAttribute(new QName("about", rdfNs), "info:fedora/".concat(foxml.getPid()));
        Element hasModel = description.addElement(new QName("hasModel", Namespaces.fedora_model));
        hasModel.addAttribute(new QName("resource", rdfNs), "info:fedora/model:".concat(model));
        Element itemId = description.addElement(new QName("itemID", Namespaces.oai));
        itemId.addText(foxml.getPid());
        Element krameriusPolicy = description.addElement(new QName("policy", krameriusNs));
        krameriusPolicy.addText("policy:".concat(policy.toString().toLowerCase()));
        return doc;
    }

    public static Element createModsCollectionEl() {
        Element modsCollection = DocumentHelper.createElement(new QName("modsCollection", Namespaces.mods));
        modsCollection.add(Namespaces.mods);
        String modsSchema = "http://www.loc.gov/standards/mods/v3/mods-3-3.xsd";
        modsCollection.addAttribute("schemaLocation", Namespaces.mods.getURI() + " " + modsSchema);
        return modsCollection;
    }

    public static void addRelationshipToRelsExt(Document relsExtDoc, Foxml foxml, String reference) {
        Element descriptionEl = findRelsExtDescriptionElement(relsExtDoc);
        Element referenceEl = descriptionEl.addElement(new QName(reference, Namespaces.kramerius));
        String resourceStr = "info:fedora/".concat(foxml.getPid());
        referenceEl.addAttribute(new QName("resource", Namespaces.rdf), resourceStr);
    }

    public static void addElementToRelsExt(Document relsExtDoc, String elementName, Namespace elementNs, String elementValue) {
        Element descriptionEl = findRelsExtDescriptionElement(relsExtDoc);
        Element element = null;
        if (elementNs == null) {
            element = descriptionEl.addElement(elementName);
        } else {
            element = descriptionEl.addElement(new QName(elementName, elementNs));
        }
        element.addText(elementValue);
    }

    private static Element findRelsExtDescriptionElement(Document relsExt) {
        XPath descriptionXPath = Dom4jUtils.createXPath("/rdf:RDF/rdf:Description");
        return (Element) descriptionXPath.selectSingleNode(relsExt);
    }

    public static void removeSchema(Document doc) {
        XPath xpath = Dom4jUtils.createXPath("/*/@xsi:schemaLocation");
        Node title = xpath.selectSingleNode(doc);
        title.detach();
    }
}
